package com.leofee.utils;

import com.leofee.common.BaseException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.util.Assert;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

@Slf4j
public class BeanUtil extends BeanUtils {

    public static <T> T copyProperties(Object source, Class<T> targetClass) {
        T target;
        try {
            target = targetClass.newInstance();
            copyProperties(source, target);
        } catch (Exception e) {
            throw new BaseException(e);
        }
        return target;
    }

    public static void copyPropertiesIgnoreNull(Object src, Object target) {
        copyProperties(src, target, ReflectUtil.getNullPropertyNames(src));
    }

    public static Map<String, Object> transBeanToMap(Object src) {
        Map<String, Object> resultMap = new HashMap<>();

        Field[] allFields = ReflectUtil.getAllFields(src);

        if (allFields.length > 0) {
            for (Field field : allFields) {
                Object value = ReflectUtil.getFieldValue(src, field);
                resultMap.put(field.getName(), value);
            }
        }
        return resultMap;
    }

    public static <T> T transMapToBean(Map<String, Object> src, Class<T> targetClass) {
        Assert.notNull(targetClass, "targetClass can not be null!");
        Assert.notEmpty(src, "source must not be empty!");

        T bean;
        try {
            bean = targetClass.newInstance();
        } catch (InstantiationException | IllegalAccessException e) {
            throw new BaseException(e);
        }

        Field[] beanFields = ReflectUtil.getAllFields(bean);

        if(!CollectionUtil.isEmpty(beanFields)){
            for (Field field : beanFields) {

                if(src.containsKey(field.getName())){
                    ReflectUtil.openAccessible(field);
                    try {
                        field.set(bean, src.get(field.getName()));
                    } catch (IllegalAccessException e) {
                        log.error("Bean class [" + targetClass +"] set field ["+field.getName() +"] value [" + "] error!");
                    }
                }
            }
        }
        return bean;
    }
}
